package com.my.chapter14;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

public class practice16 {
    public static void main(String[] args) {
        P16_CoffeeGenerator.main(args);
    }
}

class Coffee2{
    private static long counter = 0;
    private final long id = counter++;

    private static
    List<Factory<? extends Coffee2>> coffeeFactories =
            Arrays.asList(new Americano2.Factory(),
                    new Breve2.Factory(), new Latte2.Factory(),
                    new Mocha2.Factory(), new Cappuccino2.Factory());
    private static Random rand = new Random(47);
    public static Coffee2 createRandom() {
        int n = rand.nextInt(coffeeFactories.size());
        return coffeeFactories.get(n).create();
    }

    @Override
    public String toString() {
        return getClass().getSimpleName() + " " + id;
    }
}

class Latte2 extends Coffee2{
    public static class Factory
    implements com.my.chapter14.Factory<Latte2>{

        @Override
        public Latte2 create() {
            return new Latte2();
        }
    }
}

class Mocha2 extends Coffee2{
    public static class Factory
            implements com.my.chapter14.Factory<Mocha2>{

        @Override
        public Mocha2 create() {
            return new Mocha2();
        }
    }
}

class Cappuccino2 extends Coffee2{
    public static class Factory
            implements com.my.chapter14.Factory<Cappuccino2>{

        @Override
        public Cappuccino2 create() {
            return new Cappuccino2();
        }
    }
}

class Americano2 extends Coffee2{
    public static class Factory
            implements com.my.chapter14.Factory<Americano2>{

        @Override
        public Americano2 create() {
            return new Americano2();
        }
    }
}

class Breve2 extends Coffee2{
    public static class Factory
            implements com.my.chapter14.Factory<Breve2>{

        @Override
        public Breve2 create() {
            return new Breve2();
        }
    }
}

class P16_CoffeeGenerator
        implements Iterable<Coffee2>{
    public P16_CoffeeGenerator() {}
    private int size = 0;
    public P16_CoffeeGenerator(int sz) { size = sz; }
    public Coffee2 next() { return Coffee2.createRandom(); }
    class CoffeeIterator implements Iterator<Coffee2> {
        int count = size;
        public boolean hasNext() { return count > 0; }
        public Coffee2 next() {
            count--;
            return P16_CoffeeGenerator.this.next();
        }
        public void remove() {} // Not implemented
    };
    public Iterator<Coffee2> iterator() {
        return new CoffeeIterator();
    }
    public static void main(String[] args) {
        for(Coffee2 c : new P16_CoffeeGenerator(10))
            System.out.println(c);
    }
}